<?php


namespace app\api\controller;

class AuthApp extends ApiBase
{
	public function check()
	{
		$validate = \think\Validate::make(["auth" => "require"], ["auth.require" => "授权信息 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$auth = \think\Db::name("app_auth_user")->where(["appid" => $this->project["id"], "auth" => $this->input["auth"]])->find();
		if (empty($auth)) {
			$this->response(10091, "授权不存在");
		}
		if ($auth["disable"] == 1) {
			$this->response(10092, "授权被禁用");
		}
		\think\Db::startTrans();
		try {
			$date = date("Y-m-d H:i:s");
			$user_safe_config = json_decode($this->project["user_safe_config"], true);
			$machine_code_binding_top_limit = !empty($user_safe_config["machine_code_binding_top_limit"]) ? $user_safe_config["machine_code_binding_top_limit"] : \app\common\model\DefaultConfig::UserMachineCodeBindingTopLimit;
			if ($auth["machine_code_binding_top_limit"] != 0) {
				$machine_code_binding_top_limit = $auth["machine_code_binding_top_limit"];
			}
			if (!empty($user_safe_config["machine_code_verify"])) {
				if (!isset($this->input["machine_code"]) || $this->input["machine_code"] == "") {
					$this->response(10093, "当前缺少机器码参数machine_code");
				}
				if (!verifyMachineCode($this->input["machine_code"], $auth["machine_code"], $machine_code_binding_top_limit)) {
					$this->response(10094, "机器码校验失败");
				}
			}
			if (empty($this->project["user_verify_mode"])) {
				if ($auth["endtime"] < time()) {
					$this->response(10095, "授权时长已到期");
				}
			} else {
				if ($this->project["user_verify_mode"] == 1) {
				} elseif ($this->project["user_verify_mode"] == 2) {
				}
			}
			$user_machine_code = getUserMachineCodeList($auth["machine_code"]);
			if (!empty($this->input["machine_code"]) && !in_array($this->input["machine_code"], $user_machine_code) && count($user_machine_code) < $machine_code_binding_top_limit) {
				$user_machine_code[] = $this->input["machine_code"];
				\think\Db::name("app_auth_user")->where(["id" => $auth["id"]])->update(["machine_code" => json_encode($user_machine_code, JSON_UNESCAPED_UNICODE)]);
			}
			$today = \think\helper\Time::today();
			if ($auth["acttime"] < $today[0]) {
				\app\common\server\StatisticsData::increases($this->project["id"], \app\common\model\AppData::AuthAppUserActive, 1);
			}
			$online_machine_upper_limit = $user_safe_config["online_machine_upper_limit"] ?? \app\common\model\DefaultConfig::UserOnlineMachineUpperLimit;
			if ($auth["online_machine_upper_limit"] != 0) {
				$online_machine_upper_limit = $auth["online_machine_upper_limit"];
			}
			$minimum_active_time = time() - ($user_safe_config["online_time_difference"] ?? \app\common\model\DefaultConfig::AppUserHeartbeatInterval);
			$machine_code = $this->input["machine_code"] ?? "";
			$current_online_list = \think\Db::name("app_auth_user_login_machine")->where([["appid", "=", $this->project["id"]], ["uid", "=", $auth["id"]], ["active_time", ">", $minimum_active_time], ["machine_code", "<>", $machine_code], ["force_offline_status", "=", 0], ["token_status", "=", 0]])->order("login_time", "asc")->select();
			if ($online_machine_upper_limit <= count($current_online_list) && $online_machine_upper_limit > 0) {
				if (empty($user_safe_config["online_machine_upper_limit_login_scheme"])) {
					$this->response(10096, "当前无法登录,已在其他设备登录");
				} else {
					if ($user_safe_config["online_machine_upper_limit_login_scheme"] == 1) {
						\think\Db::name("app_auth_user_login_machine")->where(["id" => $current_online_list[0]["id"]])->update(["token_status" => 1, "token" => ""]);
					}
				}
			}
			$login_machine = \think\Db::name("app_auth_user_login_machine")->where(["appid" => $this->project["id"], "uid" => $auth["id"], "machine_code" => $machine_code])->find();
			$binding_ip_list = json_decode($auth["binding_ip_list"], true) ?? [];
			$machine_binding_ip_list = $login_machine ? json_decode($login_machine["binding_ip_list"], true) ?? [] : [];
			if (!empty($user_safe_config["ip_verify"])) {
				$ip_binding_top_limit = $user_safe_config["ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserIpUpperLimit;
				if ($auth["ip_binding_top_limit"] != 0) {
					$ip_binding_top_limit = $auth["ip_binding_top_limit"];
				}
				$machine_ip_binding_top_limit = $user_safe_config["machine_ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserMachineIpBindingTopLimit;
				if ($auth["machine_ip_binding_top_limit"] != 0) {
					$machine_ip_binding_top_limit = $auth["machine_ip_binding_top_limit"];
				}
				if ($ip_binding_top_limit > 0 && !in_array($this->client_ip, $binding_ip_list) && $ip_binding_top_limit <= count($binding_ip_list)) {
					$this->response(10097, "您的IP:" . $this->client_ip . "没有在绑定IP列表内无法进行登录");
				} else {
					if (!in_array($this->client_ip, $binding_ip_list)) {
						$binding_ip_list[] = $this->client_ip;
					}
				}
				if ($machine_ip_binding_top_limit > 0 && !in_array($this->client_ip, $machine_binding_ip_list) && $machine_ip_binding_top_limit <= count($machine_binding_ip_list)) {
					$this->response(10098, "您的IP:" . $this->client_ip . "没有在本设备绑定IP列表内无法进行登录");
				} else {
					if (!in_array($this->client_ip, $machine_binding_ip_list)) {
						$machine_binding_ip_list[] = $this->client_ip;
					}
				}
			}
			\think\Db::name("app_auth_user")->where(["id" => $auth["id"]])->update(["acttime" => time(), "force_offline_status" => 0, "binding_ip_list" => json_encode($binding_ip_list)]);
			$token = GenerateToken(["id" => $auth["id"], "startTime" => time()]);
			if ($login_machine) {
				$token_info = json_decode(hex2bin($login_machine["token"]), true);
				if (!checkUserTokenInvalid($user_safe_config, $token_info) && empty($user_safe_config["token_update_mechanism"]) && $token_info) {
					$token = $login_machine["token"];
				}
				\think\Db::name("app_auth_user_login_machine")->where(["id" => $login_machine["id"]])->update(["ip" => $this->client_ip, "token" => $token, "machine_info" => $this->input["machine_info"] ?? "", "login_time" => time(), "active_time" => time(), "token_status" => 0, "force_offline_status" => 0, "binding_ip_list" => json_encode($machine_binding_ip_list)]);
			} else {
				\think\Db::name("app_auth_user_login_machine")->insert(["appid" => $this->project["id"], "uid" => $auth["id"], "machine_code" => $machine_code, "machine_info" => $this->input["machine_info"] ?? "", "ip" => $this->client_ip, "token" => $token, "login_time" => time(), "active_time" => time(), "binding_ip_list" => json_encode($machine_binding_ip_list)]);
			}
			$surplusTime = $auth["endtime"] - time();
			$data = ["authInfo" => ["id" => $auth["id"], "auth" => $auth["auth"], "addtime" => $auth["addtime"], "endtime" => $auth["endtime"], "is_forever_auth" => $auth["is_forever_auth"], "private_data" => (object) get_app_user_private_data($this->project, $auth["private_data"], "user"), "token" => $token, "point" => $auth["point"]], "surplusTime" => ["second" => $surplusTime, "minute" => intval($surplusTime % 86400 % 3600 / 60), "hour" => intval($surplusTime % 86400 / 3600), "day" => intval($surplusTime / 86400)], "expireTimeStr" => date("Y-m-d H:i:s", $auth["endtime"])];
			\think\Db::commit();
			$this->response(Code::success, "登录成功", $data);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function revise_private_data()
	{
		$validate = \think\Validate::make(["auth" => "require", "field" => "require", "content" => "require"], ["auth.require" => "授权信息 不能为空！", "field.require" => "字段名 不能为空！", "content.require" => "修改内容 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $auth) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\AuthAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $auth);
		}
		\think\Db::startTrans();
		try {
			$user_private_data_config = json_decode($this->project["user_private_data_config"], true);
			$private_data = json_decode($auth["private_data"], true);
			$field_exist = false;
			$current_field_config = [];
			if ($user_private_data_config) {
				foreach ($user_private_data_config as $private_data_item) {
					if ($private_data_item["field"] == $this->input["field"]) {
						$field_exist = true;
						$current_field_config = $private_data_item;
						break;
					}
				}
			}
			if ($field_exist) {
				if (empty($current_field_config["authority"]["revise"])) {
					$this->response(10111, "没有修改权限");
				}
				$original_content = $private_data[$this->input["field"]] ?? "";
				$private_data[$this->input["field"]] = $this->input["content"];
				\think\Db::name("app_auth_user")->where(["id" => $auth["id"]])->update(["private_data" => json_encode($private_data, JSON_FORCE_OBJECT)]);
				\think\Db::commit();
				$this->response(Code::success, "修改成功", ["original_content" => $original_content, "new_content" => $this->input["content"]]);
			} else {
				$this->response(10112, "字段不存在");
			}
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function self_service_unbinding()
	{
		$validate = \think\Validate::make(["auth" => "require"], ["auth.require" => "授权信息 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$user_safe_config = json_decode($this->project["user_safe_config"], true);
		$verify = new \app\api\common\entity\AuthAppUserVerify();
		list($verify_code, $auth) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $auth);
		}
		if (!getUserMachineCodeList($auth["machine_code"])) {
			$this->response(10113, "当前未绑定机器码无需解绑");
		}
		\think\Db::startTrans();
		try {
			if (!empty($user_safe_config["self_service_unbinding"]["open"])) {
				if (!empty($user_safe_config["self_service_unbinding"]["interval"]) && $auth["self_service_unbinding_time"] > time()) {
					$this->response(10114, "解绑时间未到");
				}
				$self_service_unbinding_time = time() + $user_safe_config["self_service_unbinding"]["interval"];
				if (!empty($user_safe_config["self_service_unbinding"]["frequency_limit_type"])) {
					list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($user_safe_config["self_service_unbinding"]["frequency_limit_type"]);
					$count = \think\Db::name("app_auth_user_unbinding_log")->where([["auth_id", "=", $auth["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end]])->count();
					if ($user_safe_config["self_service_unbinding"]["frequency_limit_value"] <= $count) {
						$this->response(10115, "当前时间不可解绑");
					}
				}
				if (!empty($user_safe_config["self_service_unbinding"]["deduction_time"])) {
					if ($auth["endtime"] - $user_safe_config["self_service_unbinding"]["deduction_time"] < time()) {
						$this->response(10116, "解绑失败,您的剩余时长不足以解绑扣除");
					} else {
						$logid = \app\api\common\auth\Finance::set($auth, "endtime", $auth["endtime"] - $user_safe_config["self_service_unbinding"]["deduction_time"], 0, "自助解绑扣除时长", \app\common\model\AuthAppModel::UserEndTimeLogSourceSelfUnbinding);
					}
				}
				$update = ["machine_code" => "", "self_service_unbinding_time" => $self_service_unbinding_time, "force_offline_status" => 1];
				if (!empty($user_safe_config["self_service_unbinding"]["clear_binding_ip_list"])) {
					$update["binding_ip_list"] = "";
				}
				\think\Db::name("app_auth_user")->where(["id" => $auth["id"]])->update($update);
				if (!empty($user_safe_config["self_service_unbinding"]["clear_machine_binding_ip_list"])) {
					\think\Db::name("app_auth_user_login_machine")->where(["uid" => $auth["id"]])->update(["binding_ip_list" => ""]);
				}
				\think\Db::name("app_auth_user_unbinding_log")->insert(["appid" => $auth["appid"], "auth_id" => $auth["id"], "time" => time(), "source" => \app\common\model\AuthAppModel::UserUnBindingLogSourceSelfUnbinding]);
				\think\Db::commit();
				$this->response(Code::success, "解绑成功", []);
			} else {
				$this->response(10117, "未开启自助解绑功能");
			}
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public static function verify_user($project, $apiInfo, $apiConfig, $input, \app\api\common\entity\AuthAppUserVerify $verify) : array
	{
		try {
			$user_safe_config = json_decode($project["user_safe_config"], true);
			$auth_app_config = json_decode($project["auth_app_config"], true);
			if (isset($user_safe_config["token_verify_open"]) && $user_safe_config["token_verify_open"]) {
				$verify->setToken(true);
			}
			if (isset($user_safe_config["machine_code_verify"]) && $user_safe_config["machine_code_verify"]) {
				$verify->setMachineCode(true);
			} else {
				$verify->setMachineCode(false);
			}
			if (isset($user_safe_config["ip_verify"]) && $user_safe_config["ip_verify"]) {
				$verify->setIp(true);
			}
			if ($apiConfig && !empty($apiConfig["verify_user_token"])) {
				if ($apiConfig["verify_user_token"] === 1) {
					$verify->setToken(true);
				} elseif ($apiConfig["verify_user_token"] === 2) {
					$verify->setToken(false);
				}
			}
			if ($apiConfig && !empty($apiConfig["verify_machine_code"])) {
				if ($apiConfig["verify_machine_code"] === 1) {
					$verify->setMachineCode(true);
				} elseif ($apiConfig["verify_machine_code"] === 2) {
					$verify->setMachineCode(false);
				}
			}
			if ($apiConfig && !empty($apiConfig["verify_ip"])) {
				if ($apiConfig["verify_ip"] === 1) {
					$verify->setIp(true);
				} elseif ($apiConfig["verify_ip"] === 2) {
					$verify->setIp(false);
				}
			}
			if ($apiInfo["id"] == 73) {
				if (empty($user_safe_config["self_service_unbinding"]["verify_user_token"])) {
					$verify->setToken(false);
				} else {
					$verify->setToken(true);
				}
				if (empty($user_safe_config["self_service_unbinding"]["verify_original_machine"])) {
					$verify->setMachineCode(false);
				} else {
					$verify->setMachineCode(true);
				}
				if (empty($user_safe_config["self_service_unbinding"]["verify_ip"])) {
					$verify->setIp(false);
				} else {
					$verify->setIp(true);
				}
			}
			if ($apiInfo["id"] == 82) {
				if (empty($auth_app_config["change_binding_config"]["verify_user_token"])) {
					$verify->setToken(false);
				} else {
					$verify->setToken(true);
				}
				if (empty($auth_app_config["change_binding_config"]["verify_original_machine"])) {
					$verify->setMachineCode(false);
				} else {
					$verify->setMachineCode(true);
				}
			}
			if ($apiInfo["id"] == 77) {
				$verify->setToken(true);
			}
			$auth = \think\Db::name("app_auth_user")->where(["appid" => $input["appid"], "auth" => $input["auth"] ?? ""])->find();
			if (empty($auth)) {
				return [10099, "授权不存在"];
			}
			if ($auth["disable"] == 1) {
				return [10100, "授权被禁用"];
			}
			if ($verify->isEndtime()) {
				if ($auth["endtime"] < time()) {
					return [10101, "授权时长已到期"];
				}
			}
			if ($apiInfo["verify_user"] !== 0) {
				if ($verify->isMachineCode()) {
					if (!isset($input["machine_code"]) || $input["machine_code"] == "") {
						return [10102, "当前缺少机器码参数machine_code"];
					}
					$machine_code_binding_top_limit = !empty($user_safe_config["machine_code_binding_top_limit"]) ? $user_safe_config["machine_code_binding_top_limit"] : \app\common\model\DefaultConfig::UserMachineCodeBindingTopLimit;
					if ($auth["machine_code_binding_top_limit"] != 0) {
						$machine_code_binding_top_limit = $auth["machine_code_binding_top_limit"];
					}
					if (!verifyMachineCode($input["machine_code"], $auth["machine_code"], $machine_code_binding_top_limit)) {
						return [10103, "机器码校验失败"];
					}
				}
				$login_machine = \think\Db::name("app_auth_user_login_machine")->where(["appid" => $project["id"], "uid" => $auth["id"], "machine_code" => $input["machine_code"] ?? ""])->find();
				if ($verify->isToken()) {
					if (empty($login_machine) || empty($input["user_token"]) || $login_machine["token"] != $input["user_token"]) {
						return [10104, "用户token校验失败"];
					}
					if ($login_machine["token_status"] == 1) {
						return [10105, "已在其他设备登录"];
					}
					if ($login_machine["token_status"] == 3) {
						return [10106, "登录状态失效"];
					}
					$token_info = json_decode(hex2bin($input["user_token"]), true);
					if ($auth["force_offline_status"] == 1 || $login_machine["force_offline_status"] == 1) {
						return [10107, "您被强制下线"];
					}
					if (checkUserTokenInvalid($user_safe_config, $token_info)) {
						return [10108, "用户token失效"];
					}
				}
				if ($verify->isIp()) {
					$binding_ip_list = json_decode($auth["binding_ip_list"], true) ?? [];
					$machine_binding_ip_list = $login_machine ? json_decode($login_machine["binding_ip_list"], true) ?? [] : [];
					$ip_binding_top_limit = $user_safe_config["ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserIpUpperLimit;
					if ($auth["ip_binding_top_limit"] != 0) {
						$ip_binding_top_limit = $auth["ip_binding_top_limit"];
					}
					$machine_ip_binding_top_limit = $user_safe_config["machine_ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserMachineIpBindingTopLimit;
					if ($auth["machine_ip_binding_top_limit"] != 0) {
						$machine_ip_binding_top_limit = $auth["machine_ip_binding_top_limit"];
					}
					if ($ip_binding_top_limit > 0 && !in_array(client_ip, $binding_ip_list)) {
						return [10109, "绑定ip验证失败,您的IP:" . client_ip . "没有在绑定IP列表内"];
					}
					if ($machine_ip_binding_top_limit > 0 && !in_array(client_ip, $machine_binding_ip_list)) {
						return [10110, "绑定ip验证失败,您的IP:" . client_ip . "没有在本设备绑定IP列表内"];
					}
				}
			}
			return [Code::success, $auth, $login_machine ?? []];
		} catch (\Exception $e) {
			return [Code::fail, "系统错误:" . $e->getMessage()];
		}
	}
	public function get_auth_info()
	{
		$validate = \think\Validate::make(["auth" => "require"], ["auth.require" => "授权 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$auth = \think\Db::name("app_auth_user")->where(["appid" => $this->project["id"], "auth" => $this->input["auth"]])->find();
		if (empty($auth)) {
			$this->response(10118, "授权不存在");
		}
		if (isset($this->input["update_active"])) {
			$verify = new \app\api\common\entity\AuthAppUserVerify();
			$verify->setToken(true);
			$verify->setEndtime(false);
			list($verify_code, $auth) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
			if ($verify_code !== Code::success) {
				$this->response($verify_code, $auth);
			}
			\think\Db::name("app_auth_user")->where(["id" => $auth["id"]])->update(["acttime" => time()]);
			$machine_code = $this->input["machine_code"] ?? "";
			$login_machine = \think\Db::name("app_auth_user_login_machine")->where(["appid" => $this->project["id"], "uid" => $auth["id"], "machine_code" => $machine_code])->find();
			if ($login_machine) {
				\think\Db::name("app_auth_user_login_machine")->where(["id" => $login_machine["id"]])->update(["active_time" => time()]);
			}
		}
		$surplusTime = $auth["endtime"] - time();
		$data = ["cardInfo" => ["id" => $auth["id"], "auth" => $auth["auth"], "addtime" => $auth["addtime"], "endtime" => $auth["endtime"], "is_forever_auth" => $auth["is_forever_auth"], "point" => $auth["point"]], "surplusTime" => ["second" => $surplusTime, "minute" => intval($surplusTime % 86400 % 3600 / 60), "hour" => intval($surplusTime % 86400 / 3600), "day" => intval($surplusTime / 86400)], "expireTimeStr" => date("Y-m-d H:i:s", $auth["endtime"])];
		$this->response(Code::success, "获取成功", $data);
	}
	public function use_card()
	{
		$validate = \think\Validate::make(["auth" => "require", "card" => "require"], ["auth.require" => "授权信息 不能为空！", "card.require" => "卡密 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$card = findCardCaseSensitive("app_auth_card", ["appid" => $this->project["id"], "card" => $this->input["card"]]);
		if (empty($card)) {
			$this->response(10119, "卡密不存在");
		}
		if ($card["status"] == 1) {
			$this->response(10120, "卡密已使用");
		}
		try {
			\think\Db::startTrans();
			if ($card["agent_id"]) {
				$appBinding = \think\Db::name("app_agent_binding")->where(["agent_id" => $card["agent_id"]])->find();
				if ($appBinding && $appBinding["card_disable"]) {
					$this->response(10121, "此卡由于上级相关权限被关闭,已作废不可使用");
				}
			}
			$auth = \think\Db::name("app_auth_user")->where(["appid" => $this->project["id"], "auth" => $this->input["auth"]])->find();
			$useUid = $auth["id"] ?? 0;
			if ($card["type"] == 0) {
				if (empty($auth)) {
					$isSystemAuthUnpaid = isSystemAuthUnpaid();
					if ($isSystemAuthUnpaid && \think\Db::name("app_auth_user")->where(["appid" => $this->project["id"]])->count() >= \app\common\model\FreeQuota::AuthAppUserQuota) {
						return ["code" => Code::fail, "msg" => "当前授权为基础版,一个应用最多只能授权" . \app\common\model\FreeQuota::AuthAppUserQuota . "个用户" . \app\common\model\DefaultConfig::SystemAuthUnpaidSuffixText];
					}
					$time_type = $card["time_type"];
					$time_value = empty($card["time_value"]) ? 1 : $card["time_value"];
					$endtime = \app\common\helper\Time::computing_time($time_type, $time_value, time());
					$useUid = \think\Db::name("app_auth_user")->insertGetId(["appid" => $this->project["id"], "auth" => $this->input["auth"], "addtime" => time(), "endtime" => $endtime, "agent_id" => $card["agent_id"]]);
					\think\Db::name("app_auth_user_change_log")->insert(["appid" => $this->project["id"], "uid" => $useUid, "new" => $this->input["auth"], "source" => \app\common\model\AuthAppModel::UserChangeBindingLogSourceInit, "time" => time(), "remarks" => "首次激活授权，使用卡密：" . $card["card"]]);
					\app\common\server\StatisticsData::increases($this->project["id"], \app\common\model\AppData::AuthAppNewUserActivation, 1);
				} else {
					$useUid = $auth["id"];
					if ($auth["is_forever_auth"] == 1) {
						$this->response(10122, "您的授权时长已是永久到期无法继续续费时长");
					}
					$time_type = $card["time_type"];
					$time_value = empty($card["value"]) ? 1 : $card["value"];
					$endtime = \app\common\helper\Time::computing_time($time_type, $time_value, $auth["endtime"]);
					\app\api\common\auth\Finance::set($auth, "endtime", $endtime, 0, "使用卡密{$card["card"]}充值", \app\common\model\AuthAppModel::UserEndTimeLogSourceUseCard);
				}
			} elseif ($card["type"] == 1) {
				if (!$useUid) {
					$this->response(10268, "授权信息不存在");
				}
				\app\api\common\auth\Finance::set($auth, "point", $card["value"], 0, "使用卡密{$card["card"]}充值", \app\common\model\AuthAppModel::UserPointLogSourceRechargeableCard);
			}
			\think\Db::name("app_auth_card")->where(["id" => $card["id"]])->update(["usetime" => time(), "status" => 1, "useuid" => $useUid]);
			\think\Db::commit();
			$this->response(Code::success, "使用成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "系统错误:" . $e->getMessage(), $e->getTrace());
		}
	}
	public function increase_or_decrease_time()
	{
		$validate = \think\Validate::make(["auth" => "require", "type" => "require|in:0,1", "value" => "require|number", "remarks" => "require"], ["auth.require" => "授权 不能为空！", "type.require" => "操作类型 不能为空！", "value.require" => "操作数量 不能为空！", "remarks.require" => "备注 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$verify = new \app\api\common\entity\AuthAppUserVerify();
		$verify->setStatus(true);
		list($verify_code, $auth) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $auth);
		}
		$auth_app_config = json_decode($this->project["auth_app_config"], true);
		if (empty($auth_app_config["time_config"]["api_increase_open"]) && $this->input["type"] == 0) {
			$this->response(10123, "未开启增加功能");
		}
		if (empty($auth_app_config["time_config"]["api_reduce_open"]) && $this->input["type"] == 1) {
			$this->response(10124, "未开启减少功能");
		}
		if (!empty($auth_app_config["time_config"]["api_increase_maximum"]) && $this->input["value"] > $auth_app_config["time_config"]["api_increase_maximum"] && $this->input["type"] == 0) {
			$this->response(10125, "增加数量不能超过" . $auth_app_config["time_config"]["api_increase_maximum"]);
		}
		if (!empty($auth_app_config["time_config"]["api_increase_minimum"]) && $this->input["value"] < $auth_app_config["time_config"]["api_increase_minimum"] && $this->input["type"] == 0) {
			$this->response(10126, "增加数量不能小于" . $auth_app_config["time_config"]["api_increase_minimum"]);
		}
		if (!empty($auth_app_config["time_config"]["api_reduce_maximum"]) && $this->input["value"] > $auth_app_config["time_config"]["api_reduce_maximum"] && $this->input["type"] == 1) {
			$this->response(10127, "减少数量不能超过" . $auth_app_config["time_config"]["api_reduce_maximum"]);
		}
		if (!empty($auth_app_config["time_config"]["api_reduce_minimum"]) && $this->input["value"] < $auth_app_config["time_config"]["api_reduce_minimum"] && $this->input["type"] == 1) {
			$this->response(10128, "减少数量不能小于" . $auth_app_config["time_config"]["api_reduce_minimum"]);
		}
		if (!empty($auth_app_config["time_config"]["api_increase_frequency_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($auth_app_config["time_config"]["api_increase_frequency_limit_type"]);
			$count = \think\Db::name("app_auth_user_finance_log")->where([["user_id", "=", $auth["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "endtime"], ["source", "=", \app\common\model\AuthAppModel::UserEndTimeLogSourceClientApi]])->count();
			if ($auth_app_config["time_config"]["api_increase_frequency_limit_value"] <= $count) {
				$this->response(10129, "周期次数已上限");
			}
		}
		if (!empty($auth_app_config["time_config"]["api_increase_quantity_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($auth_app_config["time_config"]["api_increase_quantity_limit_type"]);
			$sum = \think\Db::name("app_auth_user_finance_log")->where([["user_id", "=", $auth["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "endtime"], ["source", "=", \app\common\model\AuthAppModel::UserEndTimeLogSourceClientApi]])->sum("number");
			if ($sum + $this->project["value"] > $auth_app_config["time_config"]["api_increase_quantity_limit_value"]) {
				$this->response(10130, "周期数量已上限");
			}
		}
		if ($auth["is_forever_auth"] == 1) {
			$this->response(10131, "不支持增减本身已是永久授权时长的用户");
		}
		\think\Db::startTrans();
		try {
			if ($this->input["type"] == 0) {
				$endtime = $auth["endtime"] + $this->input["value"];
			} else {
				$endtime = $auth["endtime"] - $this->input["value"];
			}
			$logid = \app\api\common\auth\Finance::set($auth, "endtime", $endtime, $this->input["type"], "客户端API操作,备注:" . $this->input["remarks"], \app\common\model\AuthAppModel::UserEndTimeLogSourceClientApi);
			\think\Db::commit();
			$this->response(Code::success, "操作成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function query_auth_exist()
	{
		$validate = \think\Validate::make(["auth" => "require"], ["auth.require" => "授权信息 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$auth = \think\Db::name("app_auth_user")->where(["appid" => $this->project["id"], "auth" => $this->input["auth"]])->find();
		$this->response(Code::success, "查询成功", ["result" => !empty($auth), "resultInt" => \intval(!empty($auth))]);
	}
	public function logout()
	{
		$validate = \think\Validate::make(["auth" => "require"], ["auth.require" => "授权信息 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$verify = new \app\api\common\entity\AuthAppUserVerify();
		$verify_user = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
		$verify_code = $verify_user[0];
		$auth = $verify_user[1];
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $auth);
		}
		$login_machine = $verify_user[2];
		\think\Db::startTrans();
		try {
			\think\Db::name("app_auth_user_login_machine")->where(["id" => $login_machine["id"]])->update(["token_status" => 3]);
			\think\Db::commit();
			$this->response(Code::success, "操作成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function disable()
	{
		$validate = \think\Validate::make(["auth" => "require"], ["auth.require" => "授权信息 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$verify = new \app\api\common\entity\AuthAppUserVerify();
		list($verify_code, $auth) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $auth);
		}
		\think\Db::name("app_auth_user")->where(["id" => $auth["id"]])->update(["disable" => 1]);
		$this->response(Code::success, "操作成功");
	}
	public function increase_or_decrease_points()
	{
		$validate = \think\Validate::make(["auth" => "require", "type" => "require|in:0,1", "value" => "require|number", "remarks" => "require"], ["auth.require" => "用户ID 不能为空！", "type.require" => "操作类型 不能为空！", "value.require" => "操作数量 不能为空！", "remarks.require" => "备注 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\AuthAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$auth_app_config = json_decode($this->project["auth_app_config"], true);
		if (empty($auth_app_config["point_config"]["api_increase_open"]) && $this->input["type"] == 0) {
			$this->response(10132, "未开启增加功能");
		}
		if (empty($auth_app_config["point_config"]["api_reduce_open"]) && $this->input["type"] == 1) {
			$this->response(10133, "未开启减少功能");
		}
		if (!empty($auth_app_config["point_config"]["api_increase_maximum"]) && $this->input["value"] > $auth_app_config["point_config"]["api_increase_maximum"] && $this->input["type"] == 0) {
			$this->response(10134, "增加数量不能超过" . $auth_app_config["point_config"]["api_increase_maximum"]);
		}
		if (!empty($auth_app_config["point_config"]["api_increase_minimum"]) && $this->input["value"] < $auth_app_config["point_config"]["api_increase_minimum"] && $this->input["type"] == 0) {
			$this->response(10135, "增加数量不能小于" . $auth_app_config["point_config"]["api_increase_minimum"]);
		}
		if (!empty($auth_app_config["point_config"]["api_reduce_maximum"]) && $this->input["value"] > $auth_app_config["point_config"]["api_reduce_maximum"] && $this->input["type"] == 1) {
			$this->response(10136, "减少数量不能超过" . $auth_app_config["point_config"]["api_reduce_maximum"]);
		}
		if (!empty($auth_app_config["point_config"]["api_reduce_minimum"]) && $this->input["value"] < $auth_app_config["point_config"]["api_reduce_minimum"] && $this->input["type"] == 1) {
			$this->response(10137, "减少数量不能小于" . $auth_app_config["point_config"]["api_reduce_minimum"]);
		}
		if (!empty($auth_app_config["point_config"]["api_increase_frequency_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($auth_app_config["point_config"]["api_increase_frequency_limit_type"]);
			$count = \think\Db::name("app_auth_user_finance_log")->where([["user_id", "=", $user["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "point"], ["source", "=", \app\common\model\AuthAppModel::UserPointLogSourceClientApi]])->count();
			if ($auth_app_config["point_config"]["api_increase_frequency_limit_value"] <= $count) {
				$this->response(10138, "周期次数已上限");
			}
		}
		if (!empty($auth_app_config["point_config"]["api_increase_quantity_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($auth_app_config["point_config"]["api_increase_quantity_limit_type"]);
			$sum = \think\Db::name("app_auth_user_finance_log")->where([["user_id", "=", $user["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "point"], ["source", "=", \app\common\model\AuthAppModel::UserPointLogSourceClientApi]])->sum("number");
			if ($sum + $this->project["value"] > $auth_app_config["point_config"]["api_increase_quantity_limit_value"]) {
				$this->response(10139, "周期数量已上限");
			}
		}
		if ($this->input["type"] == 1 && $user["point"] < $this->input["value"]) {
			$this->response(10140, "当前数量不足以减少扣除");
		}
		\think\Db::startTrans();
		try {
			$logid = \app\api\common\auth\Finance::set($user, "point", $this->input["value"], $this->input["type"], "客户端API操作,备注:" . $this->input["remarks"], \app\common\model\AuthAppModel::UserPointLogSourceClientApi);
			\think\Db::commit();
			$this->response(Code::success, "操作成功", ["original_point" => $user["point"], "new_point" => \think\Db::name("app_auth_user")->where(["id" => $user["id"]])->value("point", 0)]);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function self_service_change_binding()
	{
		$validate = \think\Validate::make(["auth" => "require", "new_auth" => "require"], ["auth.require" => "授权信息 不能为空！", "new_auth.require" => "新授权信息 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$auth_app_config = json_decode($this->project["auth_app_config"], true);
		$verify = new \app\api\common\entity\AuthAppUserVerify();
		list($verify_code, $auth) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $auth);
		}
		\think\Db::startTrans();
		try {
			if (!empty($auth_app_config["change_binding_config"]["open"])) {
				if (!\think\Db::name("app_auth_user")->where(["appid" => $this->project["id"], "auth" => $this->input["new_auth"]])->find()) {
					$this->response(10141, "该信息已存在授权,请更换");
				}
				if (!empty($auth_app_config["change_binding_config"]["interval"]) && $auth["self_service_change_binding_time"] > time()) {
					$this->response(10142, "可换绑时间未到(" . date("Y-m-Y-H-i-s", $auth["self_service_change_binding_time"]) . ")");
				}
				$self_service_change_binding_time = time() + $auth_app_config["change_binding_config"]["interval"];
				if (!empty($auth_app_config["change_binding_config"]["frequency_limit_type"])) {
					list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($auth_app_config["change_binding_config"]["frequency_limit_type"]);
					$count = \think\Db::name("app_auth_user_change_log")->where([["uid", "=", $auth["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end]])->count();
					if ($auth_app_config["change_binding_config"]["frequency_limit_value"] <= $count) {
						$this->response(10143, "当前时间不可换绑");
					}
				}
				if (!empty($auth_app_config["change_binding_config"]["deduction_time"])) {
					if ($auth["endtime"] - $auth_app_config["change_binding_config"]["deduction_time"] < time()) {
						$this->response(10144, "换绑失败,您的剩余时长不足以换绑扣除");
					} else {
						$logid = \app\api\common\auth\Finance::set($auth, "endtime", $auth["endtime"] - $auth_app_config["change_binding_config"]["deduction_time"], 0, "自助换绑扣除时长", \app\common\model\AuthAppModel::UserEndTimeLogSourceSelfChangeBinding);
					}
				}
				\think\Db::name("app_auth_user")->where(["id" => $auth["id"]])->update(["auth" => $this->input["new_auth"], "self_service_change_binding_time" => $self_service_change_binding_time]);
				\think\Db::name("app_auth_user_change_log")->insert(["appid" => $auth["appid"], "uid" => $auth["id"], "original" => $this->input["auth"], "new" => $this->input["new_auth"], "time" => time(), "source" => \app\common\model\AuthAppModel::UserChangeBindingLogSourceClientApiSelf]);
				if (!empty($auth_app_config["change_binding_config"]["attach_unbinding_machine"])) {
					\think\Db::name("app_auth_user")->where(["id" => $auth["id"]])->update(["machine_code" => "", "force_offline_status" => 1]);
					\think\Db::name("app_auth_user_unbinding_log")->insert(["appid" => $auth["appid"], "card_id" => $auth["id"], "time" => time(), "source" => \app\common\model\AuthAppModel::UserUnBindingLogSourceChangeAuthBinding]);
				}
				\think\Db::commit();
				$this->response(Code::success, "换绑成功", []);
			} else {
				$this->response(10145, "未开启自助换绑功能");
			}
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function get_card_info()
	{
		$validate = \think\Validate::make(["card" => "require"], ["card.require" => "卡密 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$card = findCardCaseSensitive("app_auth_card", ["appid" => $this->project["id"], "card" => $this->input["card"]]);
		if (empty($card)) {
			$this->response(10146, "卡密不存在");
		}
		$this->response(Code::success, "获取成功", ["card" => $card["card"], "type" => $card["type"], "time_type" => $card["time_type"], "value" => $card["value"], "addtime" => $card["addtime"], "usetime" => $card["usetime"], "status" => $card["status"], "agent_id" => $card["agent_id"], "batch_id" => $card["batch_id"], "useuid" => $card["useuid"]]);
	}
	public function create_renewal_order()
	{
		$validate = \think\Validate::make(["pay_type" => "require|in:1,2,3", "type" => "require", "value" => "require|number|>=:1", "user" => "require"], ["pay_type.require" => "请选择支付方式", "type.require" => "开通/续费类型 不能为空", "value.require" => "开通/续费面值 不能为空", "user.require" => "开通/续费授权 不能为空"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$result = \app\common\service\AppCardBuy::createRenewalOrder($this->input);
		if ($result["code"] != 1) {
			$this->response(Code::fail, $result["msg"]);
		}
		$pay_url = getsiteurl() . "/index/buy/pay/order_id/" . $result["data"]["id"];
		if (!empty($this->input["return_url"])) {
			$pay_url .= "?return_url=" . urlencode($this->input["return_url"]);
		}
		$this->response(Code::success, $result["msg"], array_merge($result["data"], ["pay_url" => $pay_url]));
	}
}